package com.whut.userservice.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.whut.clcommon.exception.BadRequestException;
import com.whut.clcommon.exception.DbException;
import com.whut.clcommon.utils.UserContext;
import com.whut.userservice.domain.po.User;
import com.whut.userservice.domain.po.UserAttention;
import com.whut.userservice.domain.po.UserFollowInfo;
import com.whut.userservice.domain.vo.UserFansAndAttentionsVO;
import com.whut.userservice.domain.vo.UserSimpleVO;
import com.whut.userservice.service.IUserAttentionService;
import com.whut.userservice.service.IUserFollowInfoService;
import com.whut.userservice.service.IUserFollowService;
import com.whut.userservice.service.IUserService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.extension.plugins.pagination.Page.of;

@Service
public class UserFollowServiceImpl implements IUserFollowService {
    @Resource
    private IUserService userService;

    @Resource
    private IUserAttentionService userAttentionService;

    @Resource
    private IUserFollowInfoService userFollowInfoService;

    private static final Long MAX_PAGE_SIZE = 100L;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void follow(Long followId) {
        // 1. 获取当前用户ID
        Long userId = UserContext.getUser();
        if (userId == null) {
            throw new BadRequestException("请先登录");
        }
        if (followId.equals(userId)) {
            throw new BadRequestException("不能关注自己");
        }
        // 2. 判断当前用户是否已经关注了该用户
        if (userAttentionService.lambdaQuery()
                .eq(UserAttention::getUserId, userId)
                .eq(UserAttention::getAttentionId, followId)
                .one() != null) {
            throw new BadRequestException("已经关注过该用户");
        }
        try {
            // 往user_attention表中插入数据
            UserAttention userAttention = new UserAttention();
            userAttention.setUserId(userId);
            userAttention.setAttentionId(followId);
            userAttention.setIsMutual(0);
            // 判断对方是否关注过我
            if (userAttentionService.lambdaQuery()
                    .eq(UserAttention::getUserId, followId)
                    .eq(UserAttention::getAttentionId, userId).one() != null) {
                // 互相关注
                userAttention.setIsMutual(1);
                userAttentionService.lambdaUpdate()
                        .eq(UserAttention::getUserId, followId)
                        .eq(UserAttention::getAttentionId, userId)
                        .set(UserAttention::getIsMutual, 1)
                        .update();
            }
            userAttentionService.save(userAttention);
        } catch (Exception e) {
            throw new DbException("关注失败，可能是数据库出问题了");
        }


        try {
            // 更新user_follow_info表中的关注数和粉丝数
            // userId的关注数加1
            userFollowInfoService.lambdaUpdate()
                    .eq(UserFollowInfo::getUserId, userId)
                    .setSql("attention_count = attention_count + 1")  // 原子更新操作
                    .update();
            // followId的粉丝数加1
            userFollowInfoService.lambdaUpdate()
                    .eq(UserFollowInfo::getUserId, followId)
                    .setSql("fans_count = fans_count + 1")  // 原子更新操作
                    .update();
        } catch (Exception e) {
            throw new DbException("关注失败，可能是数据库出问题了");
        }
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void unfollow(Long followId) {
        // 1. 获取当前用户ID
        Long userId = UserContext.getUser();
        if (userId == null) {
            throw new BadRequestException("请先登录");
        }
        if (followId.equals(userId)) {
            throw new BadRequestException("不能关注自己");
        }
        // 2. 没有关注，就不能取关
        if (userAttentionService.lambdaQuery()
                .eq(UserAttention::getUserId, userId)
                .eq(UserAttention::getAttentionId, followId)
                .one() == null) {
            throw new BadRequestException("还没有关注该用户");
        }
        // 3. 取关
        try {
            if (userAttentionService.lambdaQuery()
                    .eq(UserAttention::getUserId, followId)
                    .eq(UserAttention::getAttentionId, userId)
                    .one() != null) {
                userAttentionService.lambdaUpdate()
                        .eq(UserAttention::getUserId, followId)
                        .eq(UserAttention::getAttentionId, userId)
                        .set(UserAttention::getIsMutual, 0)
                        .update();
            }
            userAttentionService.lambdaUpdate()
                    .eq(UserAttention::getUserId, userId)
                    .eq(UserAttention::getAttentionId, followId)
                    .remove();
        } catch (Exception e) {
            throw new DbException("取关失败，可能是数据库出问题了");
        }
        //  4. 更新user_follow_info表中的关注数和粉丝数
        try {
            // userId的关注数减1
            userFollowInfoService.lambdaUpdate()
                    .eq(UserFollowInfo::getUserId, userId)
                    .setSql("attention_count = attention_count - 1")  // 原子更新操作
                    .update();
            // followId的粉丝数减1
            userFollowInfoService.lambdaUpdate()
                    .eq(UserFollowInfo::getUserId, followId)
                    .setSql("fans_count = fans_count - 1")  // 原子更新操作
                    .update();
        } catch (Exception e) {
            throw new DbException("关注失败，可能是数据库出问题了");
        }
    }

    @Override
    public Page<UserSimpleVO> getFans(Long userId, Long page, Long size, boolean isFans) {
        // 1. 参数校验
        if (userId == null) {
            throw new BadRequestException("用户ID不能为空");
        }
        if (page == null || page < 1) {
            page = 1L;
        }
        if (size > MAX_PAGE_SIZE) {
            size = MAX_PAGE_SIZE;
        }
        if (size < 1) {
            size = 10L;
        }
        if (!userService.lambdaQuery().eq(User::getId, userId).exists()) {
            throw new BadRequestException("用户不存在");
        }

        // 2. 使用MyBatis-Plus分页查询粉丝
        Page<UserAttention> pageInfo;
        if (isFans) {
            pageInfo = userAttentionService.lambdaQuery()
                    .eq(UserAttention::getAttentionId, userId)
                    .select(UserAttention::getUserId, UserAttention::getIsMutual)
                    .page(of(page, size));
        } else {
            pageInfo = userAttentionService.lambdaQuery()
                    .eq(UserAttention::getUserId, userId)
                    .select(UserAttention::getAttentionId, UserAttention::getIsMutual)
                    .page(of(page, size));
        }

        // 2.1.解析出和userId互关的用户ID
        List<Long> mutualIds = pageInfo.getRecords().stream()
                .filter(userAttention -> userAttention.getIsMutual() == 1)
                .map(UserAttention::getUserId)
                .collect(Collectors.toList());

        // 3.从粉丝列表中获取用户ID，然后根据用户ID查询用户信息
        List<Long> userIds;
        if (isFans) {
            userIds = pageInfo.getRecords().stream()
                    .map(UserAttention::getUserId)
                    .collect(Collectors.toList());
        } else {
            userIds = pageInfo.getRecords().stream()
                    .map(UserAttention::getAttentionId)
                    .collect(Collectors.toList());
        }

        // 4.查询用户信息
        List<User> userList = userService.lambdaQuery()
                .in(User::getId, userIds)
                .list();


        // 5.把User转化成UserVO
        List<UserSimpleVO> voList = new ArrayList<>();
        for (User user : userList) {
            UserSimpleVO userSimpleVO = new UserSimpleVO();
            BeanUtils.copyProperties(user, userSimpleVO);
            if (mutualIds.contains(userSimpleVO.getId())) {
                userSimpleVO.setRelationship(3);
            } else {
                userSimpleVO.setRelationship(2);
            }
            voList.add(userSimpleVO);
        }

        // 6. 封装Page返回
        Page<UserSimpleVO> result = new Page<>(page, size, pageInfo.getTotal());
        result.setRecords(voList);
        return result;

    }

    @Override
    public UserFansAndAttentionsVO getFansAndAttentionCount(Long userId) {
        UserFollowInfo followInfo = userFollowInfoService.lambdaQuery()
                .eq(UserFollowInfo::getUserId, userId)
                .select(UserFollowInfo::getFansCount, UserFollowInfo::getAttentionCount)
                .one();
        return new UserFansAndAttentionsVO(followInfo.getFansCount(), followInfo.getAttentionCount());
    }


}
